<template>
  <div v-loading="state.loading" class="keyword-analytics-container">
    <div class="main-layout">
      <!-- 输入区域 -->
      <el-card class="input-card" shadow="hover">
        <template #header>
          <div class="card-header">
            <h2><el-icon><el-icon-edit /></el-icon> 提示词分析工具</h2>
            <div class="summary-stats">
              <el-tag type="primary">总词数: {{ totalKeywords }}</el-tag>
              <el-tag type="success">唯一词: {{ uniqueKeywords }}</el-tag>
              <el-tag type="warning">屏蔽词: {{ excludedKeywords.length }}</el-tag>
            </div>
          </div>
        </template>

        <el-input
          v-model="inputText"
          type="textarea"
          :rows="5"
          placeholder="请输入提示词，用逗号分隔（如：风景,人像,夜景,风景）"
          clearable
          @input="handleInput"
          class="keyword-input"
        />

        <div class="action-bar">
          <el-button type="primary" @click="processKeywords" :icon="Refresh" >
            重新统计
          </el-button>
          <el-button type="danger" @click="resetAll" :icon="Delete" >
            全部重置
          </el-button>
          <el-button type="primary" @click="scanFolder" icon="ele-Folder" >选择文件夹</el-button>
        </div>
      </el-card>

      <!-- 屏蔽面板 -->
      <el-card class="exclude-card" shadow="hover">
        <template #header>
          <div class="card-header">
            <h3><el-icon><el-icon-view /></el-icon> 屏蔽提示词</h3>
            <el-switch
              v-model="exclusionEnabled"
              active-text="启用屏蔽"
              inactive-text="禁用屏蔽"
            />
          </div>
        </template>

        <div class="exclude-controls">
          <el-select
            v-model="excludedKeywords"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="添加要屏蔽的提示词"
            style="width: 100%"
            :loading="selectLoading"
            :filter-method="filterKeywords"
            :remote-method="remoteFilterKeywords"
            remote
            reserve-keyword
          >
            <el-option
              v-for="(item, index) in filteredOptions"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>

          <div class="exclude-actions">
            <el-button type="danger" @click="clearExclusions"  :icon="CircleClose">
              清空屏蔽
            </el-button>
            <el-button @click="addFromLowFreq"  :icon="Bottom">
              添加低频词
            </el-button>
          </div>
        </div>

        <div v-if="excludedKeywords.length" class="excluded-tags">
          <el-tag
            v-for="(word, index) in paginatedExcluded"
            :key="index"
            closable
            type="danger"
            effect="plain"
            @close="removeExcluded(word)"
            class="excluded-tag"
          >
            {{ word }}
          </el-tag>
          <el-pagination
            v-if="excludedKeywords.length > pageSize"
            small
            layout="prev, pager, next"
            :total="excludedKeywords.length"
            :page-size="pageSize"
            v-model:current-page="excludedPage"
            class="excluded-pagination"
          />
        </div>
        <div v-else class="empty-exclude">
          <el-empty description="未添加屏蔽词" :image-size="60" />
        </div>
      </el-card>
    </div>

    <!-- 统计结果区域 -->
    <el-card class="results-card" shadow="always">
      <template #header>
        <div class="card-header">
          <h2><el-icon><el-icon-data-analysis /></el-icon> 分析结果</h2>
          <div class="sort-controls">
            <el-radio-group v-model="sortOrder" size="default">
              <el-radio-button label="countDesc">频率降序</el-radio-button>
              <el-radio-button label="countAsc">频率升序</el-radio-button>
              <el-radio-button label="alpha">字母顺序</el-radio-button>
            </el-radio-group>
            <el-input
              v-model="searchQuery"
              placeholder="搜索关键词..."
              clearable
              size="default"
              style="width: 180px; margin-left: 10px;"
              @input="handleSearch"
            >
              <template #prefix>
                <el-icon><el-icon-search /></el-icon>
              </template>
            </el-input>
          </div>
        </div>
      </template>

      <!-- 统计结果图表 -->
      <div v-if="filteredKeywords.length" class="results-content">
        <div class="keywords-grid">
          <el-tag
            v-for="(item, index) in paginatedKeywords"
            :key="index"
            :type="item.tagType"
            :class="['keyword-tag', { 'excluded-tag': excludedSet.has(item.keyword) }]"
            effect="dark"
            closable
            @close="excludeKeyword(item.keyword)"
          >
            <span class="keyword-text">{{ item.keyword }}</span>
            <span class="keyword-count">{{ item.count }}</span>
          </el-tag>
        </div>

        <el-pagination
          v-if="filteredKeywords.length > pageSize"
          small
          layout="prev, pager, next, sizes"
          :total="filteredKeywords.length"
          :page-size="pageSize"
          :page-sizes="[100, 200, 500]"
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          class="pagination-bar"
        />

        <div class="distribution-chart">
          <div
            v-for="(item, index) in paginatedKeywords"
            :key="'bar-'+index"
            class="chart-row"
          >
            <div class="keyword-info">
              <el-tag :type="item.tagType" effect="dark" class="keyword-tag">
                <span class="keyword-text">{{ item.keyword }}</span>
                <span class="keyword-count">{{ item.count }}</span>
              </el-tag>
              <el-button
                v-if="!excludedSet.has(item.keyword)"
                size="default"
                type="danger"
                text
                :icon="CircleClose"
                @click="excludeKeyword(item.keyword)"
                class="exclude-btn"
              >
                屏蔽
              </el-button>
            </div>
            <div class="bar-container">
              <div
                class="bar-fill"
                :style="{ width: item.barWidth + '%' }"
                :class="item.barColor"
              ></div>
              <div class="bar-percent">{{ item.barWidth }}%</div>
            </div>
          </div>
        </div>
      </div>

      <div v-else class="empty-results">
        <el-empty description="请输入提示词或调整屏蔽设置">
          <el-icon :size="80" color="#909399"><el-icon-search /></el-icon>
        </el-empty>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, reactive, onMounted, shallowRef } from 'vue'
import {
  Edit as ElIconEdit,
  View as ElIconView,
  DataAnalysis as ElIconDataAnalysis,
  Search as ElIconSearch,
  Delete,
  Refresh,
  CircleClose,
  Bottom
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { debounce, throttle } from 'lodash-es'
import { ipcService } from '@renderer/services/ipcService'

// 常量
const MAX_KEYWORDS = 10000
const PAGE_SIZES = [100, 200, 500]

// 输入数据
const inputText = ref('')
// 初始屏蔽词
const excludedKeywords = ref<string[]>([])
// 是否启用屏蔽
const exclusionEnabled = ref(true)
// 排序方式
const sortOrder = ref('countDesc')
// 搜索查询
const searchQuery = ref('')
// 分页
const currentPage = ref(1)
const pageSize = ref(200)
const excludedPage = ref(1)

// 状态管理
const state = reactive({
  loading: false,
  selectLoading: false,
  maxCount: 0
})

// 性能优化：使用Set替代数组查找
const excludedSet = computed(() => new Set(excludedKeywords.value))

// 使用shallowRef减少响应式开销
const keywordCounts = shallowRef<Array<{keyword: string; count: number}>>([])

// 过滤后的选项（用于屏蔽选择器）
const filteredOptions = ref<string[]>([])
const allKeywords = shallowRef<string[]>([])

// 扫描文件夹功能
const scanFolder = async () => {
  state.loading = true
  try {
    const response = await ipcService.readFolderMeta();

    if (response.success) {
      inputText.value = response.combinedPrompts
      await processKeywords()
    } else {
      ElMessage.error(response.message);
    }
  } catch (err) {
    ElMessage.error('预加载脚本执行失败');
  } finally {
    state.loading = false;
  }
};

// 防抖处理输入


// 处理关键词统计（优化算法）
const processKeywords = () => {
  if (!inputText.value.trim()) {
    keywordCounts.value = []
    allKeywords.value = []
    return
  }

  // 性能优化：避免重复计算
  const text = inputText.value
  const keywords = text.split(',')
    .map(keyword => keyword.trim())
    .filter(keyword => keyword.length > 0)

  // 限制最大处理数量
  if (keywords.length > MAX_KEYWORDS) {
    ElMessage.warning(`提示词数量超过${MAX_KEYWORDS}个，仅处理前${MAX_KEYWORDS}个`)
    keywords.splice(MAX_KEYWORDS)
  }

  // 高效统计词频
  const countMap: Record<string, number> = {}
  for (const keyword of keywords) {
    countMap[keyword] = (countMap[keyword] || 0) + 1
  }

  // 转换为数组并计算最大词频
  const countsArray = Object.entries(countMap)
    .map(([keyword, count]) => ({ keyword, count }))

  // 更新最大词频
  state.maxCount = Math.max(...countsArray.map(item => item.count), 1)

  keywordCounts.value = countsArray
  allKeywords.value = countsArray.map(item => item.keyword)
}

const handleInput = debounce(processKeywords, 500)

// 重置所有
const resetAll = () => {
  inputText.value = ''
  excludedKeywords.value = []
  keywordCounts.value = []
  searchQuery.value = ''
  currentPage.value = 1
}

// 计算标签类型（预先计算）
const getTagType = (count: number) => {
  if (count >= 10) return 'danger'
  if (count >= 5) return 'warning'
  if (count >= 3) return 'primary'
  return 'success'
}

// 计算条形图颜色（预先计算）
const getBarColor = (count: number) => {
  if (count >= 10) return 'high-frequency'
  if (count >= 5) return 'medium-frequency'
  return 'low-frequency'
}

// 过滤后的关键词（应用屏蔽）
const filteredKeywords = computed(() => {
  if (!keywordCounts.value.length) return []

  let result = keywordCounts.value

  // 应用搜索过滤
  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase()
    result = result.filter(item =>
      item.keyword.toLowerCase().includes(query)
    )
  }

  // 应用屏蔽
  if (exclusionEnabled.value) {
    result = result.filter(item => !excludedSet.value.has(item.keyword))
  }

  return result
})

// 排序后的关键词（带预计算属性）
const sortedKeywords = computed(() => {
  if (!filteredKeywords.value.length) return []

  // 性能优化：避免创建新数组
  const sorted = [...filteredKeywords.value]

  // 排序
  if (sortOrder.value === 'countDesc') {
    sorted.sort((a, b) => b.count - a.count)
  } else if (sortOrder.value === 'countAsc') {
    sorted.sort((a, b) => a.count - b.count)
  } else {
    sorted.sort((a, b) => a.keyword.localeCompare(b.keyword))
  }

  // 预计算所有属性
  return sorted.map(item => ({
    ...item,
    tagType: getTagType(item.count),
    barColor: getBarColor(item.count),
    barWidth: Math.round((item.count / state.maxCount) * 100)
  }))
})

// 分页关键词
const paginatedKeywords = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return sortedKeywords.value.slice(start, end)
})

// 分页屏蔽词
const paginatedExcluded = computed(() => {
  const start = (excludedPage.value - 1) * 10
  const end = start + 10
  return excludedKeywords.value.slice(start, end)
})

// 计算总关键词数
const totalKeywords = computed(() => {
  if (!inputText.value.trim()) return 0
  return inputText.value.split(',').filter(k => k.trim()).length
})

// 计算唯一关键词数
const uniqueKeywords = computed(() => keywordCounts.value.length)

// 添加要屏蔽的关键词
const excludeKeyword = (keyword: string) => {
  if (!excludedKeywords.value.includes(keyword)) {
    excludedKeywords.value = [...excludedKeywords.value, keyword]
  }
}

// 移除屏蔽词
const removeExcluded = (keyword: string) => {
  excludedKeywords.value = excludedKeywords.value.filter(k => k !== keyword)
}

// 清空调屏
const clearExclusions = () => {
  excludedKeywords.value = []
}

// 添加低频词到屏蔽
const addFromLowFreq = () => {
  if (!keywordCounts.value.length) return

  // 获取出现次数为1的关键词
  const lowFreqWords = keywordCounts.value
    .filter(item => item.count === 1)
    .map(item => item.keyword)

  // 添加到屏蔽列表（去重）
  const newExclusions = [...new Set([...excludedKeywords.value, ...lowFreqWords])]
  excludedKeywords.value = newExclusions
}

// 搜索处理（防抖）
const handleSearch = throttle(() => {
  currentPage.value = 1
}, 300)

// 关键词过滤（用于屏蔽选择器）
const filterKeywords = (query: string) => {
  if (!query) {
    filteredOptions.value = allKeywords.value.slice(0, 100)
    return
  }

  const q = query.toLowerCase()
  filteredOptions.value = allKeywords.value
    .filter(keyword => keyword.toLowerCase().includes(q))
    .slice(0, 100)
}

// 远程过滤（虚拟滚动支持）
const remoteFilterKeywords = (query: string) => {
  state.selectLoading = true
  setTimeout(() => {
    filterKeywords(query)
    state.selectLoading = false
  }, 200)
}

// 初始化
onMounted(() => {
  // 初始加载少量示例数据
  inputText.value = '风景,人像,夜景,城市,建筑,自然,风光,动物,静物,美食,街拍,黑白,彩色,风景,人像,夜景,城市,建筑,自然,风光'
  processKeywords()
  filterKeywords('')
})
</script>

<style scoped>
.keyword-analytics-container {
  margin: 0 auto;
  padding: 20px;
  font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  color: var(--el-text-color-primary);
  max-width: 1600px;
}

.main-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

@media (max-width: 900px) {
  .main-layout {
    grid-template-columns: 1fr;
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.card-header h2, .card-header h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.summary-stats {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.input-card, .exclude-card, .results-card {
  border-radius: 12px;
  border: none;
  background: var(--el-bg-color);
  box-shadow: var(--el-box-shadow-light);
  transition: all 0.3s ease;
  border: 1px solid var(--el-border-color-lighter);
}

.input-card:hover, .exclude-card:hover {
  box-shadow: var(--el-box-shadow);
}

.results-card {
  margin-top: 20px;
}

.keyword-input {
  margin-bottom: 15px;
}

:deep(.el-textarea__inner) {
  border-radius: 10px;
  font-size: 16px;
  padding: 15px;
  border: 1px solid var(--el-border-color);
  transition: all 0.3s ease;
  background: var(--el-fill-color-lighter);
}

:deep(.el-textarea__inner:focus) {
  border-color: var(--el-color-primary);
  box-shadow: 0 0 0 2px var(--el-color-primary-light-5);
}

.action-bar {
  display: flex;
  gap: 12px;
  margin-top: 10px;
  flex-wrap: wrap;
}

.exclude-controls {
  margin-bottom: 15px;
}

.exclude-actions {
  display: flex;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.excluded-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 15px;
  min-height: 40px;
  align-items: center;
}

.excluded-pagination {
  margin-top: 10px;
  justify-content: center;
  width: 100%;
}

.excluded-tag {
  font-size: 14px;
  padding: 6px 12px;
  border-radius: 16px;
  background-color: var(--el-color-danger-light-9);
  color: var(--el-color-danger);
  border: 1px dashed var(--el-color-danger);
}

.empty-exclude {
  padding: 20px 0;
  color: var(--el-text-color-placeholder);
}

.results-content {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.sort-controls {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.distribution-chart {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 10px 0;
}

.chart-row {
  display: flex;
  align-items: center;
  gap: 15px;
}

.keyword-info {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 200px;
}

.keyword-tag {
  font-size: 14px;
  padding: 6px 14px;
  border-radius: 16px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: transform 0.2s;
  background: var(--el-fill-color);
  color: var(--el-text-color-regular);
  border: 1px solid var(--el-border-color);
}

.keyword-tag:hover {
  transform: translateY(-2px);
  box-shadow: var(--el-box-shadow-light);
}

.keyword-text {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.keyword-count {
  background: var(--el-fill-color-lighter);
  border-radius: 10px;
  padding: 2px 8px;
  font-weight: 700;
  color: var(--el-text-color-regular);
}

.bar-container {
  flex: 1;
  display: flex;
  align-items: center;
  height: 36px;
  background: var(--el-fill-color-lighter);
  border-radius: 6px;
  position: relative;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  border-radius: 6px;
  transition: width 0.5s ease-in-out;
  min-width: 30px;
  display: flex;
  align-items: center;
  padding-left: 12px;
  color: var(--el-color-white);
  font-weight: 600;
  font-size: 14px;
}

.bar-percent {
  position: absolute;
  right: 12px;
  color: var(--el-text-color-regular);
  font-weight: 600;
  font-size: 13px;
}

.low-frequency {
  background: linear-gradient(90deg, var(--el-color-success), var(--el-color-success-light-3));
}

.medium-frequency {
  background: linear-gradient(90deg, var(--el-color-warning), var(--el-color-warning-light-3));
}

.high-frequency {
  background: linear-gradient(90deg, var(--el-color-danger), var(--el-color-danger-light-3));
}

.keywords-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
  margin-top: 20px;
  max-height: 400px;
  overflow-y: auto;
  padding: 5px;
}

.keywords-grid .keyword-tag {
  width: 100%;
  justify-content: space-between;
}

.exclude-btn {
  padding: 5px;
}

.empty-results {
  padding: 40px 0;
  text-align: center;
  color: var(--el-text-color-placeholder);
}

.excluded-tag {
  opacity: 0.6;
  text-decoration: line-through;
}

.pagination-bar {
  margin-top: 15px;
  justify-content: center;
}

@media (max-width: 768px) {
  .chart-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .bar-container {
    width: 100%;
  }

  .keywords-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }

  .sort-controls {
    flex-direction: column;
    align-items: flex-start;
  }

  .action-bar {
    flex-direction: column;
  }
}

/* 滚动条优化 */
.keywords-grid::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.keywords-grid::-webkit-scrollbar-track {
  background: var(--el-fill-color-lighter);
  border-radius: 4px;
}

.keywords-grid::-webkit-scrollbar-thumb {
  background: var(--el-border-color);
  border-radius: 4px;
}

.keywords-grid::-webkit-scrollbar-thumb:hover {
  background: var(--el-border-color-hover);
}
</style>
